package com.tripcube.ai.controller;

import com.tripcube.ai.model.dto.KnowledgeRetrievalDTO;
import com.tripcube.ai.model.dto.RagChatDTO;
import com.tripcube.ai.model.vo.BaseChatVO;
import com.tripcube.ai.model.vo.KnowledgeRetrievalVO;
import com.tripcube.ai.service.KnowledgeRetrievalService;
import com.tripcube.ai.service.RagChatService;
import com.tripcube.ai.service.impl.MemoryChatServiceImpl;
import com.tripcube.common.core.web.controller.BaseController;
import com.tripcube.common.core.web.domain.AjaxResult;
import com.tripcube.common.log.annotation.Log;
import com.tripcube.common.log.enums.BusinessType;
import com.tripcube.common.security.annotation.RequiresPermissions;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

/**
 * RAG聊天控制器
 * 
 * 提供基于知识库检索增强生成（RAG）的聊天功能，包括：
 * - 单知识库RAG聊天（普通和流式）
 * - 多知识库RAG聊天
 * - 知识库检索功能
 * - 会话消息管理
 * 
 * @author alander
 */
@Tag(name = "RAG聊天", description = "基于知识库检索增强的聊天接口")
@RestController
@RequestMapping("/ai/rag")
@RequiredArgsConstructor
public class RagChatController extends BaseController {
    
    private final RagChatService ragChatService;
    private final MemoryChatServiceImpl memoryChatService;
    private final KnowledgeRetrievalService knowledgeRetrievalService;
    
    /**
     * RAG聊天
     * 
     * @param request RAG聊天请求参数
     * @return 聊天响应结果
     */
    @Operation(summary = "RAG聊天", description = "基于知识库检索增强的对话")
    @RequiresPermissions("ai:rag:chat")
    @Log(title = "RAG聊天", businessType = BusinessType.OTHER)
    @PostMapping("/chat")
    public AjaxResult ragChat(@Validated @RequestBody RagChatDTO request) {
        BaseChatVO response = ragChatService.ragChat(request);
        return success(response);
    }
    
    /**
     * RAG流式聊天
     * 
     * @param request RAG聊天请求参数
     * @return 流式聊天响应
     */
    @Operation(summary = "RAG流式聊天", description = "基于知识库检索增强的流式对话")
    @RequiresPermissions("ai:rag:chat")
    @Log(title = "RAG流式聊天", businessType = BusinessType.OTHER)
    @PostMapping(value = "/stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> ragStreamChat(@Validated @RequestBody RagChatDTO request) {
        return ragChatService.ragStreamChat(request);
    }
    
    /**
     * 内存聊天RAG
     * 
     * 使用内存聊天服务的RAG功能，支持会话记忆
     * 
     * @param request RAG聊天请求参数
     * @return 聊天响应结果
     */
    @Operation(summary = "内存聊天RAG", description = "使用现有内存聊天服务的RAG功能")
    @RequiresPermissions("ai:rag:chat")
    @Log(title = "内存聊天RAG", businessType = BusinessType.OTHER)
    @PostMapping("/memory-chat")
    public AjaxResult memoryChatRag(@Validated @RequestBody RagChatDTO request) {
        BaseChatVO response = memoryChatService.ragChat(request);
        return success(response);
    }
    
    /**
     * 内存聊天RAG流式
     * 
     * @param request RAG聊天请求参数
     * @return 流式聊天响应
     */
    @Operation(summary = "内存聊天RAG流式", description = "使用现有内存聊天服务的RAG流式功能")
    @RequiresPermissions("ai:rag:chat")
    @Log(title = "内存聊天RAG流式", businessType = BusinessType.OTHER)
    @PostMapping(value = "/memory-stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> memoryChatRagStream(@Validated @RequestBody RagChatDTO request) {
        return memoryChatService.ragStreamChat(request);
    }
    
    /**
     * 知识库检索
     */
    @Operation(summary = "知识库检索", description = "从知识库中检索相关内容")
    @RequiresPermissions("ai:rag:retrieve")
    @PostMapping("/retrieve")
    public AjaxResult retrieveKnowledge(@Validated @RequestBody KnowledgeRetrievalDTO request) {
        KnowledgeRetrievalVO result = knowledgeRetrievalService.retrieveKnowledge(request);
        return success(result);
    }
    
    /**
     * 多知识库检索
     */
    @Operation(summary = "多知识库检索", description = "从多个知识库中检索相关内容")
    @RequiresPermissions("ai:rag:retrieve")
    @PostMapping("/retrieve-multiple")
    public AjaxResult retrieveFromMultipleKnowledgeBases(
            @Parameter(description = "查询内容") @RequestParam String query,
            @Parameter(description = "知识库ID数组") @RequestParam String[] knowledgeBaseIds,
            @Parameter(description = "返回结果数量") @RequestParam(defaultValue = "10") Integer topK) {
        
        KnowledgeRetrievalVO result = knowledgeRetrievalService.retrieveFromMultipleKnowledgeBases(
                query, knowledgeBaseIds, topK);
        return success(result);
    }
    
    /**
     * 多知识库RAG聊天
     */
    @Operation(summary = "多知识库RAG聊天", description = "基于多个知识库的RAG聊天")
    @RequiresPermissions("ai:rag:chat")
    @Log(title = "多知识库RAG聊天", businessType = BusinessType.OTHER)
    @PostMapping("/multi-kb-chat")
    public AjaxResult multiKnowledgeBaseRagChat(
            @Validated @RequestBody RagChatDTO request,
            @Parameter(description = "知识库ID数组") @RequestParam String[] knowledgeBaseIds) {
        
        BaseChatVO response = ragChatService.ragChatWithMultipleKnowledgeBases(request, knowledgeBaseIds);
        return success(response);
    }
    
    /**
     * 获取会话消息记录
     */
    @Operation(summary = "获取会话消息记录")
    @RequiresPermissions("ai:rag:history")
    @GetMapping("/messages/{conversationId}")
    public AjaxResult getMessages(@Parameter(description = "会话ID") @PathVariable String conversationId) {
        return success(ragChatService.getMessages(conversationId));
    }
    
    /**
     * 清除会话消息记录
     */
    @Operation(summary = "清除会话消息记录")
    @RequiresPermissions("ai:rag:clear")
    @Log(title = "清除会话消息", businessType = BusinessType.DELETE)
    @DeleteMapping("/messages/{conversationId}")
    public AjaxResult clearMessages(@Parameter(description = "会话ID") @PathVariable String conversationId) {
        ragChatService.clearMessages(conversationId);
        return success("清除成功");
    }
}